using System;
using System.Xml.Serialization;
using System.Collections.Generic;
#if Use_Common_MudLib
using SharpMud.MudLib.Common.Resourcing;
#endif

namespace SharpMud.MudLib.SAMPLE.Environment
{
	[XmlRoot("Area")]
	public class Area :
#if Use_Common_MudLib
        Common.Environment.IArea,
#endif
        IDisposable
	{
#if Use_Common_MudLib
        protected List<Common.Environment.IRoom> _Rooms;
        protected Common.Resourcing.PrivateResourcingHelper _PrivateResourcingHelper;
#else
        protected List<SAMPLE.Environment.Room> _Rooms;
#endif
        private string							_Name;
		private string							_Author;
		private EnvironmentSystem				_HostEnvironSystem;
        private System.Guid _ID;

		public Area()
		{
#if Use_Common_MudLib
            _Rooms = new List<SharpMud.MudLib.Common.Environment.IRoom>();
            _PrivateResourcingHelper = new SharpMud.MudLib.Common.Resourcing.PrivateResourcingHelper();
#else
            _Rooms = new List<SharpMud.MudLib.SAMPLE.Environment.Room>();
#endif
			_Name = "";
			_Author = "";
			_HostEnvironSystem = null;
		}

		/// <summary>
		/// Gets or sets the name of this area
		/// </summary>
		[XmlElement("Name")]
		public string Name
		{
			get
			{
				return _Name;
			}
			set
			{
				_Name = value;
			}
		}

        [XmlElement("ID")]
        public string IDstring
        {
            get
            {
                return _ID.ToString();
            }
            set
            {
                _ID = new Guid(value);
            }
        }

        [XmlIgnore()]
        public Guid ID
        {
            get
            {
                return _ID;
            }
            set
            {
                _ID = value;
            }
        }

		
		/// <summary>
		/// Gets or sets the author of this area
		/// </summary>
		[XmlElement("Author")]
		public string Author
		{
			get
			{
				return _Author;
			}
			set
			{
				_Author = value;
			}
		}

		/// <summary>
		/// Gets all the rooms that are in this area
		/// </summary>
        public SAMPLE.Environment.Room[] Rooms
        {
			get
			{
                return _Rooms.ToArray();	
			}
			set
			{
				_Rooms.AddRange(value);
#if Use_Common_MudLib
                foreach (Common.Environment.IRoom r in value)
                {
                    if(r is IHasInstanceGuid)
                        _PrivateResourcingHelper.AddResource(r as IHasInstanceGuid);
                    if (r is IHasInstanceUri)
                        _PrivateResourcingHelper.AddResource(r as IHasInstanceUri);
                    if (r is IGuidIdentifiedResourceHost)
                        _PrivateResourcingHelper.AddResourceProxy(r as IGuidIdentifiedResourceHost);
                    if (r is IUriIdentifiedResourceHost)
                        _PrivateResourcingHelper.AddResourceProxy(r as IUriIdentifiedResourceHost);
                }
#endif
			}
		}

		/// <summary>
		/// Gets all the characters that are in this area
		/// </summary>
		public Entities.ICharacter[] GetCharactersHere()
		{
			System.Collections.ArrayList al = new System.Collections.ArrayList();
			foreach(Room r in this.Rooms)
			{
				al.AddRange(r.GetCharactersHere());
			}
			return (Entities.ICharacter[])al.ToArray(typeof(Entities.ICharacter));
		}

		/// <summary>
		/// The environment system that this mud is in
		/// </summary>
		[XmlIgnore()]
		public EnvironmentSystem HostEnvironSystem
		{
			get
			{
				return _HostEnvironSystem;
			}
		}

		/// <summary>
		/// The mud that this area is in
		/// </summary>
		[XmlIgnore()]
		public MudLib.SAMPLE.MudLibRoot HostMud
		{
			get
			{
				return (MudLib.SAMPLE.MudLibRoot)this.HostEnvironSystem.Host;
			}
		}

		/// <summary>
		/// Takes this area and ties it into the game world, by tying up loose
		/// references and such
		/// </summary>
		/// <param name="hostEnvironSystem"></param>
		public void Initialize(EnvironmentSystem hostEnvironSystem)
		{
			_HostEnvironSystem = hostEnvironSystem;

			
			//Initialize room-by-room
			foreach(Room r in this.Rooms)
			{
				r.Initialize(this);
			}
		}

		/// <summary>
		/// Looks in this area for a room matching the given RoomID and returns it is found
		/// </summary>
		public Room GetRoom(RoomID roomID)
		{
			if(roomID.Room!=null) return roomID.Room;
			foreach(Room r in this._Rooms)
			{
				if(r.RoomID.Equals(roomID))
				{
					roomID.Room = r;
					return r;
				}
			}
			return null;
		}

#if Use_Common_MudLib
        #region IArea Members

        string SharpMud.MudLib.Common.Environment.IArea.Name
        {
            get { return this.Name; }
        }

        string SharpMud.MudLib.Common.Environment.IArea.Author
        {
            get { return this.Author; }
        }

        SharpMud.MudLib.Common.Entities.ICharacter[] SharpMud.MudLib.Common.Environment.IArea.GetCharacters()
        {
            return this.GetCharactersHere();
        }

        SharpMud.MudLib.Common.Environment.IRoom[] SharpMud.MudLib.Common.Environment.IArea.GetRooms()
        {
            return this._Rooms.ToArray();
        }

        #endregion

        #region IHasInstanceGuid Members

        IGuidIdentifiedResourceHost IHasInstanceGuid.Host
        {
            get {
                return (IGuidIdentifiedResourceHost)this.HostEnvironSystem;
            }
        }

        Guid SharpMud.MudLib.Common.Resourcing.IHasInstanceGuid.ID
        {
            get
            {
                return this.ID;
            }
        }

        #endregion

        #region IGuidIdentifiedResourceHost<IRoom> Members

        SharpMud.MudLib.Common.Environment.IRoom SharpMud.MudLib.Common.Resourcing.IGuidIdentifiedResourceHost<SharpMud.MudLib.Common.Environment.IRoom>.GetResource(Guid guid)
        {
            return (_PrivateResourcingHelper.GetResource(guid) as Common.Environment.IRoom);
        }

        #endregion

        #region IGuidIdentifiedResourceHost Members

        bool SharpMud.MudLib.Common.Resourcing.IGuidIdentifiedResourceHost.IsDefined(Guid guid)
        {
            return _PrivateResourcingHelper.IsDefined(guid);
        }

        object SharpMud.MudLib.Common.Resourcing.IGuidIdentifiedResourceHost.GetResource(Guid guid)
        {
            return _PrivateResourcingHelper.GetResource(guid);
        }

        #endregion

        #region IRequiresExternalPulsing Members

        void System.Threading.IRequiresExternalPulsing.Pulse()
        {
            //throw new Exception("The method or operation is not implemented.");
        }

        #endregion
#endif

        #region IDisposable Members

        public void Dispose()
        {
            foreach(Room r in this._Rooms)
            {
                r.Dispose();
            }
        }

        #endregion
    }
}